package guoan.service;

import guoan.Exception.RestException;
import guoan.core.common.WebConfig;
import guoan.core.dto.DataGridModel;
import guoan.core.dto.PageResponse;
import guoan.core.dto.RestResponse;
import guoan.domain.Coach;
import guoan.domain.CoachItem;
import guoan.domain.CoachItemCheckPK;
import guoan.domain.RandomKey;
import guoan.domain.Student;
import guoan.domain.SysConfig;
import guoan.domain.Train;
import guoan.repository.CoachItemRepository;
import guoan.repository.CoachRepository;
import guoan.repository.SysConfigRepository;
import guoan.repository.TrainRepository;
import guoan.utils.CommonUtils;

import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;

@Service
@Transactional(readOnly = false)
public class CoachService extends PageSerivce<Coach> {
	protected final Logger log = LoggerFactory.getLogger(getClass());

	@Autowired
	private CoachRepository coachRepository;

	@Autowired
	private CoachItemRepository coachItemRepository;

	@Autowired
	private CoachItemCheckService coachItemCheckService;

	@Autowired
	private TrainRepository trainRepository;

	@Autowired
	private SysConfigRepository sysConfigRepository;

	@Autowired
	private CoachItemService coachItemService;

	@Autowired
	private TrainService trainService;

	@Autowired
	private StudentService studentService;

	@Autowired
	private RandomKeyService randomKeyService;
	@Autowired
	private CoachConfigService coachConfigService;

	/**
	 * @Title：add
	 * @Description: 本来是增加的方法，后来2货客户不需要了，所以变成修改了，但是名字不爱改了！ -_-!! FUCK
	 * @author Administrator
	 * @date 2015年5月8日 下午2:42:31
	 * @param coach
	 * @return
	 */
	@Transactional(readOnly = false)
	public RestResponse<Coach> add(Coach coach) {
		// TODO Auto-generated method stub
		Coach checkCoach = coachRepository.findOne(coach.getId());
		if (checkCoach == null) {
			return RestResponse.error("参数错误");
		}

		String oldJg = checkCoach.getJg();

		// 是否进行批量更新
		// 修改间隔进行更新，修改时间不进行更新
		boolean isAllUpdate = false;

		// 如果是修改当天的，那么需要判断修改的时候是不是现在时间之后的，对之后的信息进行清除，并更新
		if (checkCoach.getType().intValue() == 2) {
			Preconditions.checkNotNull(coach.getOpenHours(), "抱歉，参数错误！");
			String oldOh = checkCoach.getOpenHours();
			DateTime cdtime = checkCoach.getCoachTime();
			if (cdtime.getDayOfYear() == new DateTime().getDayOfYear()) {
				int countItem = coachItemRepository.countByCoachId(coach.getId()).intValue();
				if (!oldJg.equals(coach.getJg())) {// 修改了间隔
					if (countItem > 0) {// 没有过于预期的情况下不可以修改
						return RestResponse.error("已经有预约，无法修改间隔时间，请取消学员预约或取消计划后进行修改");
					} else {
						isAllUpdate = true;
					}
				} else {// 没有修改间隔
					// 比对是否修改了时间
					if (!oldOh.equals(coach.getOpenHours())) {// 进行了修改
						if (!delLastItem(oldOh, coach.getOpenHours(), checkCoach.getId(), checkCoach.getCoachTime())) {
							return RestResponse.error("修改的练车时间，小于当前时间，不允许修改");
						}
					}
				}
			} else {
				if (!oldJg.equals(coach.getJg())) {// 修改了间隔,删除所有的
					List<CoachItem> cis = coachItemRepository.findByCoachId(coach.getId());
					coachItemRepository.delete(cis);
					isAllUpdate = true;
				} else {
					delLastItem(oldOh, coach.getOpenHours(), checkCoach.getId(), checkCoach.getCoachTime());
				}
			}
			checkCoach.setUpdateTime(new DateTime());
			checkCoach.setJg(coach.getJg());
			checkCoach.setOpenHours(coach.getOpenHours());
			checkCoach.setStatus(1L);// 开启，都不开启了，你修改有用吗？
			coachRepository.save(checkCoach);
			if (isAllUpdate) {
				// 以后所有的全变了
				List<Coach> coachs = coachRepository.findByIdGreaterThanAndTrainIdAndType(checkCoach.getId(),
						checkCoach.getTrainId(), checkCoach.getType());
				for (Coach uCoach : coachs) {
					delLastItem(uCoach.getOpenHours(), coach.getOpenHours(), uCoach.getId(), uCoach.getCoachTime());
					uCoach.setUpdateTime(new DateTime());
					uCoach.setJg(checkCoach.getJg());
					uCoach.setOpenHours(checkCoach.getOpenHours());
					uCoach = coachRepository.save(checkCoach);
				}
				// 更新教练的设置,在更新了间隔后进行修改默认配置
				Train train = trainRepository.findOne(checkCoach.getTrainId());
				train.setHf(coach.getOpenHours());
				train.setJg(coach.getJg());
				train.setUpdateTime(new DateTime());
				trainRepository.save(train);
			}
		} else {// 科目三不做处理
			DateTime cdtime = checkCoach.getCoachTime();
			if (cdtime.getDayOfYear() == new DateTime().getDayOfYear()) {
				int countItem = coachItemRepository.countByCoachId(coach.getId()).intValue();
				if (countItem > 0) {// 没有过于预期的情况下不可以修改
					return RestResponse.error("已经有预约，无法修改间隔时间，请取消学员预约或取消计划后进行修改");
				}
			}
			String phs = "";
			String[] threeCoachNos = (String[]) Splitter.on(",").trimResults().splitToList(coach.getThreeCoachConfig())
					.toArray(new String[0]);
			if (!threeCoachNos[0].equals("0")) {
				threeCoachNos[0] = "上午";
			} else {
				threeCoachNos[0] = null;
			}
			if (!threeCoachNos[1].equals("0")) {
				threeCoachNos[1] = "下午";
			} else {
				threeCoachNos[1] = null;
			}
			if (!threeCoachNos[2].equals("0")) {
				threeCoachNos[2] = "晚上";
			} else {
				threeCoachNos[2] = null;
			}
			Joiner joiner = Joiner.on(",").skipNulls();
			phs = joiner.join(threeCoachNos);
			checkCoach.setUpdateTime(new DateTime());
			checkCoach.setJg(coach.getJg());
			checkCoach.setOpenHours(phs);
			checkCoach.setThreeCoachConfig(coach.getThreeCoachConfig());
			checkCoach.setStatus(1L);// 开启，都不开启了，你修改有用吗？
			coachRepository.save(checkCoach);
		}

		return RestResponse.ok(checkCoach);
	}

	/**
	 * @Title：delLastItem
	 * @Description: 删除已经预约的信息
	 * @author Administrator
	 * @date 2015年5月12日 下午2:19:52
	 * @param oldOh
	 * @param newOh
	 * @param coachId
	 * @param coachTime
	 * @return
	 */
	private Boolean delLastItem(String oldOh, String newOh, Long coachId, DateTime coachTime) {
		// 找到两处时间不一样的地方
		String[] oldOhs = oldOh.split(",");
		String[] newOhs = newOh.split(",");
		List<String> testOhs = oldOhs.length >= newOhs.length ? Lists.newArrayList(CommonUtils
				.findNotEq(oldOhs, newOhs)) : Lists.newArrayList(CommonUtils.findNotEq(newOhs, oldOhs));

		for (String moEq : testOhs) {// 轮询编号的
			// 如果在当前开始时间的变化了，则都不允许修改
			DateTime temp = new DateTime();
			int tempH = temp.getHourOfDay();
			int temoM = temp.getMinuteOfHour();
			double tempHm = Double.valueOf(tempH + "." + temoM).doubleValue();

			String[] cHos = moEq.split(":");
			double cHm = Double.valueOf(cHos[0] + "." + cHos[1]).doubleValue();
			// 如果修改的是当天的
			if (coachTime.getDayOfYear() == temp.getDayOfYear()) {
				if (cHm <= tempHm) {// 小于当前时间
					return false;
				}
			}

			List<CoachItem> coachItems = coachItemRepository.findByCoachIdAndOpenHours(coachId, moEq);
			coachItemRepository.delete(coachItems);

			coachItemCheckService.deleteByCoachIdAndOpenHours(coachId, moEq);
		}
		return true;
	}

	/**
	 * @Title：autoAdd
	 * @Description: 自动增加五天的信息,如果存在就不修改
	 * @author Administrator
	 * @date 2015年5月8日 上午10:02:55
	 * @param trainId
	 *            教练ID
	 * @param type
	 *            考试类型
	 * @return
	 */
	public RestResponse<Boolean> autoAdd(Long trainId, Long type) {
		// TODO Auto-generated method stub
		String jgs = "";
		String oh = "";
		String threeCoachConfig = null;
		if (type.intValue() == 2) {// 科目二
			// 默认是系统设置的
			int jg = WebConfig.COACH_JG_DEFALUT;
			// 其次是教练设置的
			Train train = trainRepository.findOne(trainId);
			if (!Strings.isNullOrEmpty(train.getHf()) && !Strings.isNullOrEmpty(train.getJg())) {
				jgs = train.getJg();
				oh = train.getHf();
			} else {// 最后是后台设置的
				SysConfig sysConfig = sysConfigRepository.findByK(WebConfig.SYS_CONFIG_KEY_COACH_2_JG);
				if (sysConfig != null) {
					if (!Strings.isNullOrEmpty(sysConfig.getVal())) {
						jg = Integer.valueOf(sysConfig.getVal()).intValue();
					}
				}
			}
			// 如果都没有设置，则是按照系统默认设置
			if (jgs.equals("") && oh.equals("")) {
				List<String> ohs = Lists.newArrayList();
				for (int i = 7; i < 16; i++) {
					if (i != 12) {
						ohs.add(i + ":00");
						int isMAX = 60;
						int start = 0;
						while (true) {
							start = start + jg;
							int f = start;
							if (start == isMAX) {
								break;
							}
							ohs.add(i + ":" + f);
						}
					}
				}
				jgs = String.valueOf(jg);
				oh = Joiner.on(",").join(ohs);
			}
		} else if (type.intValue() == 3) {// 科目三
			jgs = "NUN";
			oh = "上午,下午,晚上";
			threeCoachConfig = "2,1,2";
		} else {
			return RestResponse.error("参数错误");
		}

		DateTime setingDate = new DateTime(new DateTime().toString("yyyy-MM-dd"));
		// 后七天全部增加，但是已经预约的不允许修改
		for (int i = 0; i < 5; i++) {
			DateTime tempDateTime = setingDate.plusDays(i);
			Coach checkCoach = coachRepository.findByCoachTimeAndTrainIdAndType(tempDateTime, trainId, type);
			if (checkCoach == null) {
				checkCoach = new Coach();
				checkCoach.setCoachTime(tempDateTime);
				checkCoach.setCreateTime(new DateTime());
				checkCoach.setUpdateTime(checkCoach.getCreateTime());
				checkCoach.setJg(jgs);
				checkCoach.setOpenHours(oh);
				checkCoach.setType(type);
				checkCoach.setTrainId(trainId);
				checkCoach.setThreeCoachConfig(threeCoachConfig);
				checkCoach = coachRepository.save(checkCoach);
			}
		}
		return RestResponse.ok(true);
	}

	/**
	 * @Title：findCoachItemByCoachId
	 * @Description: 获得 coachId的相关报名情况
	 * @author Administrator
	 * @date 2015年4月29日 下午2:41:36
	 * @param coachId
	 * @return
	 */
	public List<CoachItem> findCoachItemByCoachId(Long coachId) {
		List<CoachItem> coachItems = coachItemRepository.findByCoachIdAndStatusOrderByOpenHoursAsc(coachId,
				CoachItem.STATUS_DEFALUT);
		Ordering<CoachItem> byLengthOrdering = new Ordering<CoachItem>() {
			@Override
			public int compare(CoachItem left, CoachItem right) {
				if (left.getCoachType() == 2) {
					double ls = Double.valueOf(left.getOpenHours().replaceAll(":", ".")).doubleValue();
					double rs = Double.valueOf(right.getOpenHours().replaceAll(":", ".")).doubleValue();
					return (ls < rs) ? -1 : ((ls > rs) ? 1 : 0);
				} else {
					int l = left.getOpenHours().equals("上午") ? 1 : (left.getOpenHours().equals("下午") ? 2 : 3);
					int r = right.getOpenHours().equals("上午") ? 1 : (right.getOpenHours().equals("下午") ? 2 : 3);
					return (l < r) ? -1 : ((l > r) ? 1 : 0);
				}

			}
		};
		Collections.sort(coachItems, byLengthOrdering);
		return coachItems;
	}

	/**
	 * @Title：findCoach
	 * @Description: 学员看3天，教练看5天的计划
	 * @author Administrator
	 * @date 2015年4月29日 下午2:53:11
	 * @param type
	 * @param userType
	 * @return
	 */
	public List<Coach> findCoach(Long type, Long userType, Long trainId) {
		DateTime toDate = new DateTime(new DateTime().toString("yyyy-MM-dd"));
		if (userType.intValue() == 2) {// 教练
			toDate = toDate.plusDays(4);
		} else if (userType.intValue() == 1) {// 学员
			toDate = toDate.plusDays(2);
		}
		return coachRepository.findByTypeAndTrainIdAndCoachTimeBetween(type, trainId,
				new DateTime(new DateTime().toString("yyyy-MM-dd")), toDate);
	}

	/**
	 * @Title：findRightItem
	 * @Description: 获得没有预约过的时间列表,正常状态下的预约
	 * @author Administrator
	 * @date 2015年4月29日 下午3:13:25
	 * @param coachId
	 * @return
	 */
	public List<String> findRightItem(Long coachId) {
		Coach coach = coachRepository.findOne(coachId);
		String openhours = coach.getOpenHours();
		Iterator<String> openHoursIter = Splitter.on(",").split(openhours).iterator();
		List<String> openHoursIterLists = Lists.newArrayList(openHoursIter);
		List<String> inItems = coachItemRepository.findOpenHoutsByCoachId(coachId);
		List<String> rItemHours = Lists.newArrayList();
		for (String s1 : openHoursIterLists) {
			boolean flag = false;
			for (String s2 : inItems) {
				if (s1.equals(s2)) {
					flag = true;
					break;
				}
			}
			if (!flag) {
				rItemHours.add(s1);
			}
		}
		return rItemHours;
	}

	/**
	 * @Title：page
	 * @Description: 预约信息分页
	 * @author Administrator
	 * @date 2015年5月12日 下午2:20:18
	 * @param dataGridModel
	 * @return
	 */
	public PageResponse<CoachItem> page(DataGridModel dataGridModel, String key) {
		// TODO Auto-generated method stub
		return coachItemService.page(dataGridModel, key);
	}

	/**
	 * @Title：cleanCoach
	 * @Description: 取消预约
	 * @author Administrator
	 * @date 2015年5月12日 下午2:20:29
	 * @param coachId
	 * @return
	 */
	public RestResponse<Coach> cleanCoach(Long coachId) {
		// TODO Auto-generated method stub

		Coach coach = coachRepository.findOne(coachId);
		Preconditions.checkNotNull(coach, "抱歉，参数错误！");
		if (coach.getStatus().intValue() == 1) {
			coach.setStatus(0L);
			coach.setUpdateTime(new DateTime());
			coachRepository.save(coach);
			// 删除所有预约
			List<CoachItem> coachItems = coachItemRepository.findByCoachIdOrderByOpenHoursAsc(coach.getId());
			coachItemRepository.delete(coachItems);
			coachItemCheckService.deleteByCoachId(coachId);

		} else {
			coach.setStatus(1L);
			coach.setUpdateTime(new DateTime());
			coachRepository.save(coach);
		}

		return RestResponse.ok(coach);
	}

	/**
	 * @Title：cleanItemCoach
	 * @Description: 取消预约
	 * @author Administrator
	 * @date 2015年5月12日 下午2:20:38
	 * @param coachItemId
	 * @return
	 */
	public RestResponse<Long> cleanItemCoach(Long coachItemId) {
		// TODO Auto-generated method stub
		CoachItem coachItem = coachItemRepository.findOne(coachItemId);
		Preconditions.checkNotNull(coachItem, "抱歉，参数错误！");
		Long coachId = coachItem.getCoachId();
		coachItem.setStatus(CoachItem.STATUS_CLEAN);// 状态为取消
		// coachItemRepository.delete(coachItem);
		coachItemRepository.save(coachItem);

		coachItemCheckService.deleteOne(new CoachItemCheckPK(coachItem.getOpenHours(), coachItem.getCoachId(),
				coachItem.getExamTime(), coachItem.getTrainId()));

		return RestResponse.ok(coachId);
	}

	public Coach findOne(Long coachId) {
		// TODO Auto-generated method stub
		return coachRepository.findOne(coachId);
	}

	public CoachItem findCoachItem(Long coachItemId, Long studentId) {
		// TODO Auto-generated method stub
		return coachItemRepository.findByIdAndStudentId(coachItemId, studentId);
	}

	public Long findCoachItemCountByStudentIdAndCoachId(Long studentId, Long coachId) {
		// TODO Auto-generated method stub
		return coachItemRepository.countByStudentIdAndCoachIdAndStatus(studentId, coachId, CoachItem.STATUS_DEFALUT);
	}

	public Long findCoachItemCountByStudentIdAndCoachIdAndOpenHours(Long studentId, Long coachId, String itemHours) {
		// TODO Auto-generated method stub
		return coachItemRepository.countByStudentIdAndCoachIdAndOpenHoursAndStatus(studentId, coachId, itemHours,
				CoachItem.STATUS_DEFALUT);
	}

	/**
	 * 根据预约ID时间段看正常的预约数
	 * 
	 * @param coachId
	 * @param itemHours
	 * @return
	 */
	public Long findCoachItemCountByCoachIdAndOpenHours(Long coachId, String itemHours) {
		// TODO Auto-generated method stub
		return coachItemRepository.countByCoachIdAndOpenHoursAndStatus(coachId, itemHours, CoachItem.STATUS_DEFALUT);
	}

	public CoachItem addCoachItem(CoachItem coachItem) {
		// TODO Auto-generated method stub
		return coachItemRepository.save(coachItem);
	}

	/**
	 * 学员的正常的可查看的预约
	 * 
	 * @param studentId
	 * @return
	 */
	public List<CoachItem> findCoachItemByStudentId(Long studentId) {
		// TODO Auto-generated method stub
		DateTime toDate = new DateTime(new DateTime().toString("yyyy-MM-dd"));
		return coachItemRepository.findByStudentIdAndStatusAndExamTimeGreaterThanEqualOrderByExamTimeAsc(studentId,
				CoachItem.STATUS_DEFALUT, toDate);
	}

	/**
	 * 练车预约正常报名总数
	 * 
	 * @param id
	 * @return
	 */
	public Long findCoachItemCountByCoachId(Long id) {
		// TODO Auto-generated method stub
		return coachItemRepository.countByCoachIdAndStatus(id, CoachItem.STATUS_DEFALUT);
	}

	/**
	 * 获得可预约的预约
	 * 
	 * @param coachId
	 * @param itemHours
	 * @return
	 */
	public CoachItem findCoachItemByCoachIdAndOpenHours(Long coachId, String itemHours) {
		// TODO Auto-generated method stub
		List<CoachItem> coachItems = coachItemRepository.findByCoachIdAndOpenHours(coachId, itemHours);
		// 如果有取消状态的预约,立即开始预约
		// 如果没有预约,返回一个空
		for (CoachItem coachItem : coachItems) {
			if (coachItem.getStatus().endsWith(CoachItem.STATUS_CLEAN)) {
				return coachItem;
			}
		}
		return null;
	}

	public String addYY(String itemHours, Long coachId, Model model, HttpServletRequest request) {
		HttpSession session = request.getSession();
		Student student = null;
		if (session.getAttribute(WebConfig.SESSION_WEIXIN_OPENID_KEY) != null) {
			String openid = (String) session.getAttribute(WebConfig.SESSION_WEIXIN_OPENID_KEY);
			student = studentService.findByStudentOpenid(openid);
			if (studentService.findByStudentOpenid(openid) == null) {// 进行学员绑定
				return "redirect:/weixin/student/oauthStudent";
			}
		} else {
			throw new RestException("请在微信中打开");
		}
		Preconditions.checkNotNull(coachId, "抱歉，参数错误！");
		Preconditions.checkNotNull(itemHours, "抱歉，参数错误！");

		// 获得当前预约练车的设置
		Coach coach = findOne(coachId);
		if (coach == null) {
			model.addAttribute("msg", "当前信息不存在");
			model.addAttribute("url", "/weixin/coach/item?coachId=" + coachId);
			return "/weixin/msg";
		}
		if (coach.getStatus().intValue() == 0) {
			model.addAttribute("msg", "当前预约计划已经取消，请更换其他日期进行预约");
			model.addAttribute("url", "/weixin/coach/coach_1_" + coach.getType());
			return "/weixin/msg";
		}

		// 12点后才可以预约
		DateTime ct = coach.getCoachTime();
		DateTime now = new DateTime();
		// 第三天的预约需要在12电话后开启.
		if (ct.getDayOfYear() - now.getDayOfYear() == 2) {
			if (now.getHourOfDay() < 12) {
				model.addAttribute("msg", "12点开始预约，请等待");
				model.addAttribute("url", "/weixin/coach/item?coachId=" + coachId);
				return "/weixin/msg";
			}
		}

		// 看参数是否正确
		String[] hm = itemHours.split(":");
		if (hm.length != 2) {
			Preconditions.checkNotNull(itemHours, "抱歉，参数错误！");
		}

		// 不允许重复选择,当前是否有正常的可以的预约
		Long ischeckItemCount = findCoachItemCountByStudentIdAndCoachIdAndOpenHours(student.getId(), coachId, itemHours);
		if (ischeckItemCount.intValue() == 1) {
			model.addAttribute("msg", "您已经成功预约过该练车时间，不可再次重复预约");
			return "/weixin/msg";
		}
		// 学员正常状态下的预约练车数量
		Long count = findCoachItemCountByStudentIdAndCoachId(student.getId(), coachId);
		// 如果是科目二
		if (coach.getType().intValue() == 2) {
			// 判断是否约了1次
			if (count.intValue() == 1) {
				model.addAttribute("msg", "每天练车最多1次");
				model.addAttribute("url", "/weixin/coach/item?coachId=" + coachId);
				return "/weixin/msg";
			}
			// 判断选择的时间段是否大于当前时间 yyyy-MM-dd hh:mm
			DateTime nowTime = new DateTime(new DateTime().getYear(), new DateTime().getMonthOfYear(),
					new DateTime().getDayOfMonth(), new DateTime().getHourOfDay(), new DateTime().getMinuteOfHour());

			DateTime coachTime = coach.getCoachTime();
			DateTime temTime = new DateTime(coachTime.getYear(), coachTime.getMonthOfYear(), coachTime.getDayOfMonth(),
					Integer.valueOf(hm[0]).intValue(), Integer.valueOf(hm[1]).intValue());
			if (nowTime.isAfter(temTime.getMillis())) {// 您所选中的练车时间比现在早，不运行选择
				model.addAttribute("msg", "您所选中的练车时间比现在早，不运行选择");
				model.addAttribute("url", "/weixin/coach/item?coachId=" + coachId);
				return "/weixin/msg";
			}
		} else if (coach.getType().intValue() == 3) {// 科目三最大1次

			if (count.intValue() == 1) {// 暂时不考虑时间问题
				model.addAttribute("msg", "每天练车最多1次");
				model.addAttribute("url", "/weixin/coach/item?coachId=" + coachId);
				return "/weixin/msg";
			}
		}

		// 科目二一个时间段只有一个预约
		RandomKey randomKey = null;
		if (coach.getType().intValue() == 2) {

			try {
				if (!coachItemCheckService.checkSave(itemHours, coachId, coach.getCoachTime(), coach.getTrainId())) {
					model.addAttribute("msg", "当前考试时间已被预约，请重新尝试别的时间");
					model.addAttribute("url", "/weixin/coach/item?coachId=" + coachId);
					return "/weixin/msg";
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				model.addAttribute("msg", "当前考试时间已被预约，请重新尝试别的时间");
				model.addAttribute("url", "/weixin/coach/item?coachId=" + coachId);
				return "/weixin/msg";
			}
			randomKey = randomKeyService.findByStudentIdAndType(student.getId(), 2L);
		} else if (coach.getType().intValue() == 3) {
			try {
				if (!check3(coach.getThreeCoachConfig(), itemHours, coachId)) {
					model.addAttribute("msg", "您所选择的练车时间已经被别人抢用");
					model.addAttribute("url", "/weixin/coach/item?coachId=" + coachId);
					return "/weixin/msg";
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				model.addAttribute("msg", "当前预约人数过多，请尝试别的时间预约");
				model.addAttribute("url", "/weixin/coach/item?coachId=" + coachId);
				return "/weixin/msg";
			}
			randomKey = randomKeyService.findByStudentIdAndType(student.getId(), 3L);
		} else {
			throw new RestException("参数错误");
		}

		// 有正确的绑定码才可以预约
		if (randomKey != null) {
			// 对取消的改为正常的,对没有的新增
			CoachItem coachItem = findCoachItemByCoachIdAndOpenHours(coachId, itemHours);
			if (coachItem == null) {
				coachItem = new CoachItem();
			}
			coachItem.setCoachId(coachId);
			coachItem.setContactNumberF(student.getContactNumberF());
			coachItem.setExamTime(coach.getCoachTime());
			coachItem.setJoinTime(new DateTime());
			coachItem.setOpenHours(itemHours);
			coachItem.setStudentKey(randomKey.getKey());
			coachItem.setStudentName(student.getStudentName());
			coachItem.setStudentNo(student.getStudentNo());
			coachItem.setStudentOpenid(student.getStudentOpenid());
			coachItem.setStudentId(student.getId());
			coachItem.setTrainId(coach.getTrainId());
			coachItem.setCoachType(coach.getType());
			Train train = trainService.findOne(coach.getTrainId());
			coachItem.setTrainName(train.getTrainName());
			coachItem.setTrainTel(train.getTrainTel());
			coachItem.setStatus(CoachItem.STATUS_DEFALUT); // 默认的状态为正常
			addCoachItem(coachItem);
		} else {
			model.addAttribute("msg", "您的绑定码不正确，请重新尝试");
			model.addAttribute("url", "/weixin/coach/item?coachId=" + coachId);
			return "/weixin/msg";
		}
		model.addAttribute("msg", "预约成功");
		model.addAttribute("url", "/weixin/coach/coach_1_" + coach.getType());
		return "/weixin/msg";
	}

	@Transactional(readOnly = false, isolation = Isolation.SERIALIZABLE, propagation = Propagation.REQUIRES_NEW, timeout = 10)
	public Boolean check3(String threeCoachConfig, String itemHours, Long coachId) {
		// 判断选择的时间段是否大于当前时间
		// 获得该预约ID下的正常的时间段与约数量
		Long coachItemCount = findCoachItemCountByCoachIdAndOpenHours(coachId, itemHours);
		String defaultThreeCoachNos = "2,1,2";
		List<String> threeCoachNos = Lists.newArrayList();
		if (threeCoachConfig != null) {
			defaultThreeCoachNos = threeCoachConfig;
		}
		threeCoachNos = Splitter.on(",").trimResults().splitToList(defaultThreeCoachNos);
		// 科目三，上午2个，下午1个，晚上2个
		if (coachItemCount.intValue() >= Integer.valueOf(threeCoachNos.get(0)).intValue() && itemHours.equals("上午")) {
			return false;
		}
		if (coachItemCount.intValue() >= Integer.valueOf(threeCoachNos.get(2)).intValue() && itemHours.equals("晚上")) {
			return false;
		}
		if (coachItemCount.intValue() >= Integer.valueOf(threeCoachNos.get(1)).intValue() && itemHours.equals("下午")) {
			return false;
		}
		return true;
	}

	public void removeLast() {
		// TODO Auto-generated method stub
		coachItemService.removeLast();
	}
}
